package models

import (
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	_ "github.com/go-sql-driver/mysql"
	"time"
)

const (
	lastService = "SELECT b.employee_id FROM sys_customer_follow a INNER JOIN ipcc_seat b ON a.app_id = b.developer_id AND a.create_by = b.name WHERE a.phone = %s AND a.app_id = %s ORDER BY a.`create_time` DESC limit 1"
)

type IpccBill struct {
	Id           uint64    `orm:"description(主键);pk;auto"`
	AppId        string    `orm:"description(企业Id)"`
	CallId       string    `orm:"description(通话Id)"`
	Caller       string    `orm:"description(主叫)"`
	Callee       string    `orm:"description(被叫)"`
	Service      string    `orm:"description(serviceId);null"`
	Number       string    `orm:"description(中继号);null"`
	Duration     uint      `orm:"description(整通电话通话时长，秒)"`
	UserDuration uint      `orm:"description(用户侧通话时长，秒)"`
	Record       string    `orm:"description(录音文件);null"`
	AnswerTime   time.Time `orm:"description(接听时间);null"`
	CallStart    time.Time `orm:"description(呼叫开始时间)"`
}

type SysCustomerFollow struct {
	Id       int
	AppId    int
	CreateBy string
}

type IpccSeat struct {
	Id         int
	Name       string
	EmployeeId string
}

var gInsterChan chan *IpccBill

const (
	max_chan_count = 10000
)

func RegisterBill() {

	orm.RegisterModel(new(IpccBill), new(SysCustomerFollow), new(IpccSeat))

	gInsterChan = make(chan (*IpccBill), 10000)

	go saveSqlRoutine()
}

func InsertBill(bill IpccBill) {

	if len(gInsterChan) < max_chan_count {
		gInsterChan <- &bill
	} else {
		logs.Error("[%v]db channel is full ,drop the bill", bill.CallId)
	}

	return
}

func GetLatestServiceId(appId, caller string) (string, error) {

	sqlStr := fmt.Sprintf(lastService, caller, appId)

	var maps []orm.Params
	o := orm.NewOrm()
	num, err := o.Raw(sqlStr).Values(&maps)
	if err == nil && num > 0 {
		value, ok := maps[0]["employee_id"]
		if ok {
			logs.Debug("获取上次跟踪坐席 :%v 数量:%v", value, num)
			return value.(string), nil
		} else {
			logs.Debug("获取上次跟踪坐席 servicId:%v", value)
			return "", nil
		}
	} else if num == 0 {
		return "", nil
	} else {
		return "", err
	}

}

func GetLatestServiceId2(appId, caller string) (string, error) {

	searchBill := &IpccBill{
		AppId:  appId,
		Caller: caller,
	}

	o := orm.NewOrm()
	err := o.QueryTable(searchBill).Filter("AppId", appId).
		Filter("Caller", caller).
		OrderBy("AnswerTime").
		One(searchBill)

	if err != nil {
		return "", err
	}

	return searchBill.Service, nil
}

func saveSqlRoutine() {

	time.Sleep(10 * time.Second)
	o := orm.NewOrm()
	for {

		newBill := <-gInsterChan

		_, err := o.Insert(newBill)
		if err != nil {
			logs.Error("write db failed:%v,bill:%v", err, *newBill)
		}
	}
}
